﻿import React, { Component} from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import actionsC from '@/store/actions.js'
import Resizable from 're-resizable'
import Draggable from 'react-draggable'
import { getCurrentNode } from '@/store/selectors'
import * as utils from '@/utils'
import randomColor from 'randomcolor'
import { observer, inject } from 'mobx-react'

let actions=actionsC()

@inject('rootStore')
@observer
class CurrentHandle extends Component {
	constructor(props) {
		super(props)
		this.state = {
			top: 0,
			left: 0,
			path: [],
			width:0,
			height: 0,
			initialPos: { //移动模式，初始坐标
				left: 0,
				top:0
			},
			dragStart:{
				x: 0,
				y: 0
			},
			drawStart: {
				x: 0,
				y: 0
			},
			drawing: false, //是否在绘制中
			draging: false,
			drawHandle:{
				width: 0,
				height: 0,
				top: 0,
				left: 0
			},
			key_x: 'margin-left',
			key_y: 'margin-top',
			display: 'none',
			currentNode: this.props.rootStore.currentDom,
			operationMode: this.props.rootStore.operationMode,
			currentDom: this.props.rootStore.currentDom,
		}
	}
	static getDerivedStateFromProps(nextProps,prevState){
		// debugger
		let {currentDom, currentNode, operationMode} = nextProps.rootStore

		let newState = {}

		if(!currentDom){
			Object.assign(newState, {
				display: 'none',
			})
			return newState
		}
		let currentNodeChange = JSON.stringify(prevState.currentNode) != JSON.stringify(currentNode)
		let currentDomChange = prevState.currentDom != currentDom
		let operationModeChange = prevState.operationMode != operationMode

		if(currentNodeChange) newState.currentNode = currentNode
		if(currentDomChange) newState.currentDom = currentDom
		if(operationModeChange) newState.operationMode = operationMode
		
		if(currentDomChange || operationModeChange || currentNodeChange){
			Object.assign(newState, {
				currentDom,
				currentNode,
				operationMode,
				top:currentDom.offsetTop,
				left:currentDom.offsetLeft,
				width:$(currentDom).outerWidth(),
				height:$(currentDom).outerHeight(),
				display:'block',
			})
		}
		Object.assign(newState, {
			initialPos:{
				left: currentDom.offsetLeft,
				top: currentDom.offsetTop,
			},
			display:'block'
		})
		if(Object.keys(newState).length!=0){
			return newState	
		}
		return null
	}
	// getSnapshotBeforeUpdate(){
		
	// }
	componentDidUpdate(prevProps, prevState, snapshot){
		// this.setPosKey(prevProps)
	}
	componentDidMount(){
		$(window).resize(()=>{
			this.sizeRivise()
		})
	}
	setPosKey(nextProp){
		const {currentNode}= nextProp
		if(_.isEmpty(currentNode)) return
		let key_x = 'margin-left'
		let key_y = 'margin-top'
		if(currentNode.positionBy.length!=0){
			switch(currentNode.positionBy[0]){
				case 'float':
					key_x = `margin-${currentNode.positionBy[1]}`
					key_y = 'margin-top'
					break;
				case 'position':
					if(currentNode.positionBy[1]!='static'){
						key_x = 'left'
						key_y = 'top'
					}
					break;
			}
		}
		this.setState({
			key_x,
			key_y
		})
	}
	// size revise
	sizeRivise(props){ 
		var dom = props ? props.currentDom : this.props.currentDom
		if(dom){
			this.setState({
				top:dom.offsetTop,
				left:dom.offsetLeft,
				width:$(dom).outerWidth(),
				height:$(dom).outerHeight()
			})
		}
	}
	onDrag(e, dis) {
		const {nodeTree, currentPath, currentNode} = this.props.rootStore;
		const {dragStart, key_x, key_y} = this.state

		let from_x = _.get(currentNode,`styles[${key_x}]`, 0)
		let from_y = _.get(currentNode,`styles[${key_y}]`, 0)
		from_x = utils.sizeToNum(`${from_x}`)
		from_y = utils.sizeToNum(`${from_y}`)
		this.props.rootStore.nodeUpdateByPath({
			path: currentPath,
			node:{
				styles:{
					[key_x]: (dis.x - dragStart.x)*(/left|margin-left/.test(key_x) ? 1 : -1) + dragStart.style.x,
					[key_y]: (dis.y - dragStart.y)*(/top|margin-top/.test(key_y) ? 1 : -1) + dragStart.style.y
				}
			}
		});
	}
	onDragStart(e, dis){
		let {key_x, key_y} = this.state
		const {currentNode} = this.props
		let marginLeft = _.get(currentNode,`styles[${key_x}]`)
		let marginTop = _.get(currentNode,`styles[${key_y}]`)
		marginLeft = marginLeft ? utils.sizeToNum(`${marginLeft}`) : 0
		marginTop = marginTop ? utils.sizeToNum(`${marginTop}`) : 0
		this.setState({
			dragStart: {
				style: {
					x: marginLeft,
					y: marginTop
				},
				x: dis.x,
				y: dis.y
			},
			draging: true
		})
	}
	onDragStop(){
		const {initialPos} = this.state
		this.setState({
			draging: false,
			left: initialPos.left,
			top: initialPos.top
		})
	}
	onResize(e, direction){
		const {dispatch, nodeTree, currentPath, sizeFix, currentNode} = this.props;
		let styles = {
			width:arguments[2].offsetWidth - sizeFix.width,
			height: arguments[2].offsetHeight - sizeFix.height,
		}
		if(!/left|right/.test(direction)){
			delete styles.width
		}
		dispatch.nodeUpdateByPath({
			path: currentPath,
			node:{
				styles
			}
		})
	}
	drawHandle(){
		const {currentDom, dispatch, tag, nodeTree, currentPath, currentNode} = this.props
		const {drawHandle} = this.state
		//path,新的节点的path
		let path = _.clone(currentPath)
		let index = 0
		let _currentPath = currentPath
		
		if($(currentDom).hasClass('emidraw-paper')){
			_currentPath = []
			index = nodeTree.length
		}else{
			index = currentNode.children.length
		}
		//dispatch.
		dispatch.addNode({
			node:{
				tag: tag,
				styles: {
					width: drawHandle.width,
					height: drawHandle.height,
					background: randomColor({luminosity: 'dark',format: 'rgba',alpha: 0.5})
				}
			},
			nodeTree: nodeTree,
			path: _currentPath
		})
		path.push(index)
		//更新当前节点的路径，触发当a前节点的设置
		setTimeout(()=>{
			dispatch.updateCurrentPath(path)
		},0)
	}
	drawStart(e){
		const {currentDom} =  this.props
		let r_pos = $(currentDom).offset()
		this.setState({
			drawing: true,
			drawStart:{
				x: e.pageX,
				y: e.pageY
			},
			drawHandle: Object.assign(this.state.drawHandle, {
				top: e.pageY -  r_pos.top,
				left: e.pageX - r_pos.left
			})
		})
		e.stopPropagation()
	}
	drawIng(e){
		const {operationMode} = this.props.rootStore
		const { drawStart, drawing } = this.state
		// 只处理draw模式的mousemove
		if(operationMode!='draw' && drawing) return
		this.setState({
			drawHandle: Object.assign(this.state.drawHandle, {
				width: e.pageX - drawStart.x,
				height: e.pageY - drawStart.y
			})
		})
		e.stopPropagation()
		// 
	}
	drawEnd(e){
		this.setState({
			drawing: false
		})
		this.drawHandle()
		e.stopPropagation()
	}
	render() {
		const {rootStore} = this.props;
		const {operationMode} = rootStore;
		const {width,height,top,left, drawing, drawHandle,display} = this.state
		var styles = {width, height, top, left, position:"absolute",display}
		var drawHandleStyle = {
			width: drawHandle.width,
			height: drawHandle.height,
			position:"absolute",
			top: drawHandle.top,
			left: drawHandle.left
		}
		console.log("operationMode", operationMode)
		switch(operationMode){
			case "move":
				return(
					<Draggable
						onDrag={this.onDrag.bind(this)}
						onStart={this.onDragStart.bind(this)}
						onStop={this.onDragStop.bind(this)}
						defaultPosition={{x: styles.left, y: styles.top}}
						position={{x: styles.left, y: styles.top}}
						>
						<div className={"current-handle "+ operationMode}
						style={{width: styles.width, height:styles.height,position:"absolute",top:0,left:0}}
						/>
					</Draggable>
				)
			case "scale":
				return(
					<Resizable
						className={"current-handle "+ operationMode}
						style={styles}
						defaultSize={{
							width: width,
							height: height
						}}
						size= {{
							width: width,
							height: height
						}}
						onResize={this.onResize.bind(this)}
						bounds="parent"
						handleClasses="emidraw-_resize-handle"
						>
					</Resizable>
				)
				break;
			case "select":
				return (
					<div className={"current-handle "+ operationMode} style={styles}>
					</div>
				)
				break;
			case "edit":
				return (
					<div className={"current-handle "+ operationMode} style={styles}>
					</div>
				)
				break;
			case "draw":
				return (
					<div
					onMouseDown={this.drawStart.bind(this)}
					onMouseUp={this.drawEnd.bind(this)}
					onMouseMove={this.drawIng.bind(this)}
					className={"current-handle "+ operationMode}
					style={styles}>
						{drawing ? 
							<div className="draw-handle"
							ref="drawHandle"
							style={drawHandleStyle}
							>
							</div>
						 :null}
					</div>
				)
				break;
			default:
				return (
					<div className={"current-handle "+ operationMode} style={styles}>
					</div>
				)
				break;
		}
	}
}

CurrentHandle.defaultProps = {
	isShow:false
};

export default CurrentHandle


